// Copyright 2009 Pigasus.
// GNU GPL v2.
// Author: John Zhang and Jordan Rupprecht.

#include "getthread.h"

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

#include <fstream>
#include <sstream>
#include <string>

#include "common.h"
#include "pigasus-types.h"
#include "threadpool.h"

using namespace std;

extern ThreadPool *get_thread_pool;
extern pthread_mutex_t *mutex_get_thread_pool;

GetThread::GetThread(int id_to_get_, Map &server_, Map *output_) {
  debug("GetThread constructor\n");
  id_to_get = id_to_get_;
  server = &server_;
  output = output_;
}

GetThread::~GetThread() { }

void GetThread::Run() {
  // Get the list of files
  // TODO: retrieve the list of files. Right now well just get pig-<id>/*
  // We could maybe have a list of files that have changed, get that, and read
  // it in; then we would grab each of those files.
  FILE *p;
  char ignore[20];
  char *err;
  string buffer;  //TODO: dynamic size
  string user = *(string*)server->Get("user");
  string host = *(string*)server->Get("host");
  debug("GetThread starting\n");
  
  // Prepare the directory for the files
  buffer = "mkdir -p out-" + IntToString(id_to_get);
  p = popen(buffer.c_str(), "r");
  while (!feof(p)) err = fgets(ignore, sizeof(ignore), p);
  pclose(p);
  
  // Get the files
  buffer = "scp -i pig_rsa " + user + "@" + host + ":pig-"
         + IntToString(id_to_get) + "/changed.tar.gz ./out-"
         + IntToString(id_to_get);
  debug("Buffer for copying tar over is %s\n", buffer.c_str());
  
  p = popen(buffer.c_str(), "r");
  while (!feof(p)) err = fgets(ignore, sizeof(ignore), p);
  pclose(p);

  // Delete the temporary pig-directory in the remote computer.
  buffer = "ssh -i pig_rsa -nT " + user + "@" + host + " \"rm -rf pig-" +
           IntToString(id_to_get) + "\"";
  debug("Buffer for deleting remote directory is %s\n", buffer.c_str());

  p = popen(buffer.c_str(), "r");
  while (!feof(p)) err = fgets(ignore, sizeof(ignore), p);
  pclose(p);
            
  // Untar and get list of changed files
  buffer = "tar -zxvf out-" + IntToString(id_to_get) + "/changed.tar.gz "
  "-C out-" + IntToString(id_to_get) + " > out-" + IntToString(id_to_get) + "/changed";
  p = popen(buffer.c_str(), "r");
  while (!feof(p)) err = fgets(ignore, sizeof(ignore), p);
  pclose(p);
            
  buffer = "./out-" + IntToString(id_to_get);
  debug("Root is %s, output is at %p\n", buffer.c_str(), output);
  debug("Size is %d\n", output->GetSize());
  output->Set("root", buffer);
    
  string stdout_file;
  ReadStringFromFile(buffer + "/stdout", stdout_file);
  output->Set("stdout", stdout_file);
  debug("GetThread %d: Stdout = %s\n", id, stdout_file.c_str());
  
  string stderr_file;
  ReadStringFromFile(buffer + "/stderr", stderr_file);
  output->Set("stderr", stderr_file);
  debug("GetThread %d: stderr = %s\n", id, stderr_file.c_str());
  
  List files;
  string changed_path = buffer + "/changed";
  ifstream ifs(changed_path.c_str());
  while (ifs.good()) {
    string s;    
    getline(ifs, s);

    if ((s == "stderr") || (s == "stdout") || (s.empty())) {
      continue;
    }

    files.Append(s);
  }
  output->Set("files", files);
  
  //Set status to done
  pthread_mutex_lock(mutex_get_thread_pool);
  get_thread_pool->SetStatus(id, kThreadStatusMarkAsDone);
  pthread_mutex_unlock(mutex_get_thread_pool);
}
